from typing import Any, Dict, Optional, Union

from sqlalchemy.orm import Session

from app.core.security import get_password_hash, verify_password
from app.models.user import User
from app.schemas.user import UserCreate, UserUpdate
from app.core.redis import redis_client

class CRUDUser:
    """用户CRUD操作类
    
    封装用户相关的数据库操作，包括创建、读取、更新和删除用户
    以及用户认证和权限检查
    """
    def get(self, db: Session, id: int) -> Optional[User]:
        """根据ID获取用户
        
        Args:
            db: 数据库会话
            id: 用户ID
            
        Returns:
            Optional[User]: 用户对象，如不存在则返回None
        """
        return db.query(User).filter(User.id == id).first()

    def get_by_email(self, db: Session, email: str) -> Optional[User]:
        """根据邮箱获取用户
        
        Args:
            db: 数据库会话
            email: 用户邮箱
            
        Returns:
            Optional[User]: 用户对象，如不存在则返回None
        """
        return db.query(User).filter(User.email == email).first()

    def get_by_username(self, db: Session, username: str) -> Optional[User]:
        """根据用户名获取用户
        
        Args:
            db: 数据库会话
            username: 用户名
            
        Returns:
            Optional[User]: 用户对象，如不存在则返回None
        """
        return db.query(User).filter(User.username == username).first()

    def get_multi(self, db: Session, *, skip: int = 0, limit: int = 100) -> list[User]:
        """获取多个用户
        
        支持分页查询用户列表
        
        Args:
            db: 数据库会话
            skip: 跳过的记录数
            limit: 返回的最大记录数
            
        Returns:
            list[User]: 用户对象列表
        """
        return db.query(User).offset(skip).limit(limit).all()

    def create(self, db: Session, *, obj_in: UserCreate) -> User:
        """创建新用户
        
        根据提供的用户创建模型创建新用户
        
        Args:
            db: 数据库会话
            obj_in: 用户创建模型
            
        Returns:
            User: 创建的用户对象
        """
        db_obj = User(
            email=obj_in.email,
            username=obj_in.username,
            hashed_password=get_password_hash(obj_in.password),
            full_name=obj_in.full_name,
            is_superuser=obj_in.is_superuser,
        )
        db.add(db_obj)
        db.commit()
        db.refresh(db_obj)
        return db_obj

    def update(self, db: Session, *, db_obj: User, obj_in: Union[UserUpdate, Dict[str, Any]]) -> User:
        """更新用户信息
        
        根据提供的更新数据更新用户信息
        
        Args:
            db: 数据库会话
            db_obj: 要更新的用户对象
            obj_in: 更新数据，可以是UserUpdate模型或字典
            
        Returns:
            User: 更新后的用户对象
        """
        if isinstance(obj_in, dict):
            update_data = obj_in
        else:
            update_data = obj_in.model_dump(exclude_unset=True)
        if update_data.get("password"):
            hashed_password = get_password_hash(update_data["password"])
            del update_data["password"]
            update_data["hashed_password"] = hashed_password
        for field in update_data:
            setattr(db_obj, field, update_data[field])
        db.add(db_obj)
        db.commit()
        db.refresh(db_obj)
        return db_obj

    def delete(self, db: Session, *, id: int) -> Optional[User]:
        """删除用户
        
        根据ID删除用户
        
        Args:
            db: 数据库会话
            id: 用户ID
            
        Returns:
            Optional[User]: 被删除的用户对象，如不存在则返回None
        """
        obj = db.query(User).get(id)
        if obj:
            db.delete(obj)
            db.commit()
        return obj

    def authenticate(self, db: Session, *, username: str, password: str) -> Optional[User]:
        """用户认证
        
        验证用户名和密码是否匹配
        
        Args:
            db: 数据库会话
            username: 用户名
            password: 明文密码
            
        Returns:
            Optional[User]: 认证成功返回用户对象，失败返回None
        """
        user = self.get_by_username(db, username=username)
        if not user:
            return None
        if not verify_password(password, user.hashed_password):
            return None
        return user

    def is_active(self, user: User) -> bool:
        """检查用户是否激活
        
        Args:
            user: 用户对象
            
        Returns:
            bool: 用户是否激活
        """
        return user.is_active

    def is_superuser(self, user: User) -> bool:
        """检查用户是否为超级管理员
        
        Args:
            user: 用户对象
            
        Returns:
            bool: 用户是否为超级管理员
        """
        return user.is_superuser

# 创建全局用户CRUD实例
user = CRUDUser()